package test.traffic;

import cn.legym.garp.gateway.traffic.rule.TrafficRule;
import cn.legym.garp.gateway.traffic.rule.TrafficRuleManager;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;

import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

/**
 * create by pipisun on 2021/9/14
 * copyright © 2017-2021 Legym Technology Co.,Ltd. All rights reserve
 * d.
 * file description:
 * last update by {} on {}
 * update description:
 */
public class TrafficRuleTestcase {

    @Test
    public void testTrafficRule() {
        TrafficRule rule = new TrafficRule();
        rule.setDynamicResource(false);
        rule.setUrlPattern("/**");// match any
        rule.setResource("test_res");
        rule.init();

        MockServerHttpRequest request = MockServerHttpRequest.get("http://some.web.site/abc")
                .queryParam("concern", "25")
                .queryParam("certain", "88")
                .build();
        Assert.assertTrue(rule.matchRule(request));

        request = MockServerHttpRequest.get("http://some.web.site").build();
        Assert.assertFalse(rule.matchRule(request));

        request = MockServerHttpRequest.post("http://some.web.site/some/path/to/resource").build();
        Assert.assertTrue(rule.matchRule(request));
    }

    @Test
    public void testTrafficRuleMatchPattern() {
        TrafficRule rule = new TrafficRule();
        rule.setDynamicResource(false);
        rule.setUrlPattern("/foo/*/bar");
        rule.setResource("test_res");
        rule.init();

        // match path
        MockServerHttpRequest request = MockServerHttpRequest.get("http://some.web.site/foo/a/bar")
                .queryParam("concern", "25")
                .queryParam("certain", "88")
                .build();
        Assert.assertTrue(rule.matchRule(request));

        request = MockServerHttpRequest.post("http://some.web.site/foo").build();
        Assert.assertFalse(rule.matchRule(request));

        request = MockServerHttpRequest.post("http://some.web.site/foo/b/bar/").build();
        Assert.assertFalse(rule.matchRule(request));

        rule = new TrafficRule();
        rule.setDynamicResource(false);
        rule.setUrlPattern("/foo/*/bar/**");
        rule.setResource("test_res");
        rule.init();

        request = MockServerHttpRequest.post("http://some.web.site/foo/b/bar/").build();
        Assert.assertTrue(rule.matchRule(request));
        request = MockServerHttpRequest.post("http://some.web.site/other/foo/b/bar").build();
        Assert.assertFalse(rule.matchRule(request));
        request = MockServerHttpRequest.post("http://some.web.site/Foo/b/bar").build();
        Assert.assertFalse(rule.matchRule(request));
    }

    @Test
    public void testTrafficRuleManager() {
        TrafficRuleManager manager = new TrafficRuleManager();

        TrafficRule rule1 = new TrafficRule();
        rule1.setDynamicResource(false);
        rule1.setUrlPattern("/foo/*/bar");
        rule1.setResource("test_res1");
        rule1.init();

        TrafficRule rule2 = new TrafficRule();
        rule2.setDynamicResource(false);
        rule2.setUrlPattern("/pathA");
        rule2.setResource("test_res2");
        rule2.init();

        // fill rules
        manager.updateData(Arrays.asList(rule1, rule2));

        MockServerHttpRequest request = MockServerHttpRequest.get("https://some.web.site/foo/a/bar")
                .queryParam("concern", "25")
                .queryParam("certain", "88")
                .build();
        Assert.assertEquals(1, manager.matchRule(request).size());
        Assert.assertEquals(rule1, Lists.newArrayList(manager.matchRule(request)).get(0));

        request = MockServerHttpRequest.post("http://some.web.site/pathA").build();
        Assert.assertEquals(1, manager.matchRule(request).size());
        Assert.assertEquals(rule2, Lists.newArrayList(manager.matchRule(request)).get(0));

        request = MockServerHttpRequest.post("http://some.web.site/pathA/123").build();
        Assert.assertTrue(manager.matchRule(request).isEmpty());

        //
        manager.updateData(Collections.emptyList());
        request = MockServerHttpRequest.post("http://some.web.site/pathA").build();
        Assert.assertTrue(manager.matchRule(request).isEmpty());

        //
        manager.updateData(Arrays.asList(rule1, rule1));
        request = MockServerHttpRequest.get("https://some.web.site/foo/CCC/bar").build();
        Assert.assertEquals(1, manager.matchRule(request).size());
        Assert.assertEquals(rule1, Lists.newArrayList(manager.matchRule(request)).get(0));
        Assert.assertEquals(1, manager.getRules().size());
        Assert.assertEquals(rule1, manager.getRules().get(rule1.getUrlPattern()));
    }
}
